package com.taxshare.seller.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.taxshare.mybatis.pager.PageHelp;
import com.taxshare.mybatis.pager.PageRequest;
import com.taxshare.mybatis.utils.DozerBeanUtil;
import com.taxshare.response.beans.Response;
import com.taxshare.seller.constant.ResultConstant;
import com.taxshare.seller.entity.GoodsManageEntity;
import com.taxshare.seller.entity.ProjectInfoEntity;
import com.taxshare.seller.entity.SellerDetialMergeEntity;
import com.taxshare.seller.entity.excel.EstateGoodsManageExcelEntity;
import com.taxshare.seller.mapper.GoodsManageMapper;
import com.taxshare.seller.view.dto.EstateGoodsManageDTO;
import com.taxshare.seller.view.dto.EstateGoodsManageExcelDTO;
import com.taxshare.seller.view.dto.ExcelDTO;
import com.taxshare.tools.util.ExcelUtil;
import com.taxshare.tools.util.UUIDUitl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @ClassName: EstateGoodsManageService
 * @Description: 地产商品管理
 * @author: hjh
 * @date: 2021/5/27 18:17
 */
@Slf4j
@Service
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public class EstateGoodsManageService extends ServiceImpl<GoodsManageMapper, GoodsManageEntity> {

    @Autowired
    ProjectService projectService;

    @Autowired
    SellerDetialMergeService sellerDetialMergeService;

    /**
     * 地产商品管理（新增）
     *
     * @param estateGoodsManageDTO
     * @return
     */
    public Response EstateGoodsManageAdd(EstateGoodsManageDTO estateGoodsManageDTO) {
        GoodsManageEntity goodsManageEntity = DozerBeanUtil.map(estateGoodsManageDTO, GoodsManageEntity.class);
        goodsManageEntity.setUuid(UUIDUitl.UUID32(false));
        goodsManageEntity.setMark("2");
        Response resp = checkProject(goodsManageEntity);
        if (!resp.SUCCESS.equals(resp.getCode())) {
            return resp;
        }
        this.save(goodsManageEntity);
        return Response.success();
    }

    /**
     * 地产商品管理【商品信息删除】
     *
     * @return
     */
    public Response EstateGoodsManageRemove(List<String> ids) {
        this.removeByIds(ids);
        return Response.success();
    }

    /**
     * 地产商品管理【商品信息编辑】
     *
     * @param estateGoodsManageDTO
     * @return
     */
    public Response EstateGoodsManageEdit(EstateGoodsManageDTO estateGoodsManageDTO) {
        GoodsManageEntity goodsManageEntity = DozerBeanUtil.map(estateGoodsManageDTO, GoodsManageEntity.class);
        Response resp = checkProject(goodsManageEntity);
        if (!resp.SUCCESS.equals(resp.getCode())) {
            return resp;
        }
        this.updateById(goodsManageEntity);
        return Response.success();
    }

    /**
     * 校验数据
     *
     * @param entity
     * @return
     */
    private Response checkProject(GoodsManageEntity entity) {
        if (StrUtil.isBlank(entity.getProjectCode())) {
            return Response.error("SEL_107");
        }
        QueryWrapper<SellerDetialMergeEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_code_max", entity.getProjectCode());
        List<SellerDetialMergeEntity> sellerDetialMergeEntityList = sellerDetialMergeService.list(queryWrapper);
        if (CollectionUtil.isEmpty(sellerDetialMergeEntityList)) {
            return Response.success();
        }
        SellerDetialMergeEntity sellerDetialMergeEntity = sellerDetialMergeEntityList.get(0);
        if (StrUtil.isBlank(sellerDetialMergeEntity.getIsMergeDetialGoodsName())) {
            sellerDetialMergeEntity.setIsMergeDetialGoodsName("0");
        }
        if (StrUtil.isBlank(sellerDetialMergeEntity.getIsMergeDetialTaxRate())) {
            sellerDetialMergeEntity.setIsMergeDetialTaxRate("0");
        }
        if ("0".equals(sellerDetialMergeEntity.getIsMergeDetialGoodsName()) && "0".equals(sellerDetialMergeEntity.getIsMergeDetialTaxRate())) {
            return Response.success();
        } else if ("1".equals(sellerDetialMergeEntity.getIsMergeDetialGoodsName())) {
            //以名称合并
            QueryWrapper<GoodsManageEntity> queryWrapperName = new QueryWrapper<>();
            queryWrapperName.eq("project_code", entity.getProjectCode());
            queryWrapperName.eq("goods_name", entity.getGoodsName());
            queryWrapperName.notIn("uuid", entity.getUuid());
            if (baseMapper.selectCount(queryWrapperName) > 0) {
                return Response.error("SEL_035");
            }
        } else {
            //税率合并
            QueryWrapper<GoodsManageEntity> queryWrapperTax = new QueryWrapper();
            queryWrapperTax.eq("project_code", entity.getProjectCode());
            queryWrapperTax.notIn("uuid", entity.getUuid());
            if ("0".equals(entity.getTaxRate())) {
                queryWrapperTax.eq("tax_rate_mark", entity.getTaxRateMark());
            }
            queryWrapperTax.eq("tax_rate", entity.getTaxRate());
            if (baseMapper.selectCount(queryWrapperTax) > 0) {
                return Response.error("SEL_036");
            }
        }
        return Response.success();
    }

    /**
     * 地产商品管理【商品信息查询】
     *
     * @param query
     * @return
     */
    public Response EstateGoodsManageQuery(PageRequest<EstateGoodsManageDTO> query) {
        EstateGoodsManageDTO estateGoodsManageDto = query.getInfo();
        QueryWrapper<GoodsManageEntity> queryWrapper = new QueryWrapper();
        if (StrUtil.isNotBlank(estateGoodsManageDto.getGoodsCode())) {
            queryWrapper.eq("goods_code", estateGoodsManageDto.getGoodsCode());
        }
        if (StrUtil.isNotBlank(estateGoodsManageDto.getGoodsName())) {
            queryWrapper.like("goods_name", estateGoodsManageDto.getGoodsName());
        }
        if (StrUtil.isNotBlank(estateGoodsManageDto.getTaxCode())) {
            queryWrapper.eq("tax_code", estateGoodsManageDto.getTaxCode());
        }
        if (StrUtil.isNotBlank(estateGoodsManageDto.getTaxName())) {
            queryWrapper.eq("tax_name", estateGoodsManageDto.getTaxName());
        }
        if (StrUtil.isNotBlank(estateGoodsManageDto.getProjectCode())) {
            queryWrapper.eq("project_code", estateGoodsManageDto.getProjectCode());
        }
        if (StrUtil.isNotBlank(estateGoodsManageDto.getProjectName())) {
            queryWrapper.like("project_name", estateGoodsManageDto.getProjectName());
        }
        if (StrUtil.isNotBlank(estateGoodsManageDto.getTaxRate())) {
            queryWrapper.eq("tax_rate", estateGoodsManageDto.getTaxRate());
        }
        queryWrapper.eq("mark", "2")
                .orderByDesc("create_time");
        IPage<GoodsManageEntity> result = PageHelp.siamplePage(this, queryWrapper, query.getPage(), GoodsManageEntity.class);
        return Response.success(result);
    }

    /**
     * 根据项目编码查询商品信息
     *
     * @param projectCode
     * @return
     */
    public Response queryGoodsByProject(String projectCode) {
        QueryWrapper<GoodsManageEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_code", projectCode);
        List<GoodsManageEntity> list = this.list(queryWrapper);
        return Response.success(list);
    }

    /**
     * 获取已启用项目信息
     *
     * @param
     * @return
     */
    public Response getProject() {
        QueryWrapper<ProjectInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("enable_tag", "0");
        List<ProjectInfoEntity> list = projectService.list(queryWrapper);
        return Response.success(list);
    }

    /**
     * 商品查询
     *
     * @param
     * @return
     */
    public Response getGoods() {
        QueryWrapper<GoodsManageEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mark", 2);
        return Response.success(this.list(queryWrapper));
    }

    /**
     * 地产商品管理信息【地产商品管理信息导入】
     *
     * @param excelFile
     */
    public Response estateGoodsManageImport(MultipartFile excelFile) {
        List<EstateGoodsManageExcelDTO> excelDTOList;
        try {
            excelDTOList = ExcelUtil.readExcel(excelFile.getInputStream(), new EstateGoodsManageExcelDTO(), EstateGoodsManageExcelDTO.class);
        } catch (IOException e) {
            log.error("上传文件异常：", e);
            return Response.error(ResultConstant.RET_P0011_CODE, ResultConstant.RET_P0011_MSG);
        }
        //循环校验
        for (EstateGoodsManageExcelDTO dto : excelDTOList) {
            String taxRate = dto.getTaxRate();
            String dutyFreeType = dto.getDutyFreeType();
            String preferentialMark = dto.getPreferentialMark();
            String preferentialName = dto.getPreferentialName();
            //必填项校验
            if (StrUtil.isEmpty(taxRate) || StrUtil.isEmpty(dto.getTaxCode()) || StrUtil.isEmpty(dto.getTaxName()) || StrUtil.isEmpty(dto.getGoodsCode()) || StrUtil.isEmpty(dto.getGoodsName()) || StrUtil.isEmpty(dto.getProjectCode()) || StrUtil.isEmpty(dto.getProjectName()) || StrUtil.isEmpty(preferentialMark)) {
                return Response.error(ResultConstant.RET_P0018CODE, ResultConstant.RET_P0018_MSG);
            }
            //优惠政策 是/否 填写规范校验
            if (!favouredPolicyJudge(preferentialMark)) {
                return Response.error(ResultConstant.RET_P0014CODE, "项目编码：" + dto.getProjectCode() + "，商品编码：" + dto.getGoodsCode() + "的税编信息，" + ResultConstant.RET_P0014_MSG);
            }
            //税率填写规格校验
            if (!rateJudge(taxRate)) {
                return Response.error(ResultConstant.RET_P0016CODE, "项目编码：" + dto.getProjectCode() + "，商品编码：" + dto.getGoodsCode() + "的税编信息，" + ResultConstant.RET_P0016_MSG);
            }
            //优惠政策是否和优惠类型的逻辑校验
            Response response;
            int i = preferentialJudge(preferentialMark, preferentialName);
            response =
                    i == 1 ? Response.error(ResultConstant.RET_P0021CODE, "项目编码：" + dto.getProjectCode() + "，商品编码：" + dto.getGoodsCode() + "的税编信息，" + ResultConstant.RET_P0021_MSG) :
                            (i == 2 ? Response.error(ResultConstant.RET_P0022CODE, "项目编码：" + dto.getProjectCode() + "，商品编码：" + dto.getGoodsCode() + "的税编信息，" + ResultConstant.RET_P0022_MSG) :
                                    (i == 3 ? Response.error(ResultConstant.RET_P0015CODE, "项目编码：" + dto.getProjectCode() + "，商品编码：" + dto.getGoodsCode() + "的税编信息，" + ResultConstant.RET_P0015_MSG) : Response.success()));
            if (!response.SUCCESS.equals(response.getCode())) {
                return response;
            }
            //0税率和免税类型逻辑校验
            int t = taxRateJudge(taxRate, dutyFreeType);
            response =
                    t == 1 ? Response.error(ResultConstant.RET_P0017CODE, "项目编码：" + dto.getProjectCode() + "，商品编码：" + dto.getGoodsCode() + "的税编信息，" + ResultConstant.RET_P0017_MSG) :
                            (t == 2 ? Response.error(ResultConstant.RET_P0019CODE, "项目编码：" + dto.getProjectCode() + "，商品编码：" + dto.getGoodsCode() + "的税编信息，" + ResultConstant.RET_P0019_MSG) :
                                    (t == 3 ? Response.error(ResultConstant.RET_P0020CODE, "项目编码：" + dto.getProjectCode() + "，商品编码：" + dto.getGoodsCode() + "的税编信息，" + ResultConstant.RET_P0020_MSG) : Response.success()));
            if (!response.SUCCESS.equals(response.getCode())) {
                return response;
            }
            //优惠政策标识 转换
            dto.setPreferentialMark(mkMap.get(preferentialMark).toString());
            GoodsManageEntity goodsManageEntity = DozerBeanUtil.map(dto, GoodsManageEntity.class);
            GoodsManageEntity existsEntity = invoiceExistsSubmit(dto);
            if (existsEntity == null) {
                Response resp = checkProject(goodsManageEntity);
                if (!resp.SUCCESS.equals(resp.getCode())) {
                    return resp;
                }
                //添加 税编信息
                goodsManageEntity.setUuid(UUIDUitl.UUID32(false));
                goodsManageEntity.setMark("2");
                goodsManageEntity.setTaxRateMark(goodsManageEntity.getDutyFreeType());
                this.save(goodsManageEntity);
            } else {
                Response resp = checkProject(goodsManageEntity);
                if (!resp.SUCCESS.equals(resp.getCode())) {
                    return resp;
                }
                //更新 税编信息
                goodsManageEntity.setUuid(existsEntity.getUuid());
                goodsManageEntity.setUpdateTime(new Date());
                this.updateById(goodsManageEntity);
            }
        }
        return Response.success();
    }

    /**
     * 发票提交判断
     *
     * @param dto
     * @return
     */
    private GoodsManageEntity invoiceExistsSubmit(EstateGoodsManageExcelDTO dto) {
        String goodsCode = dto.getGoodsCode();
        String projectCode = dto.getProjectCode();
        String getProjectName = dto.getProjectName();
        GoodsManageEntity estateGoodsManageEntity = baseMapper.queryEstateGoods(goodsCode, projectCode, getProjectName);
        return estateGoodsManageEntity;
    }

    /**
     * 地产商品管理【地产商品信息导出】
     *
     * @param response
     * @return
     */
    public void estateGoodsManageExport(HttpServletRequest request, HttpServletResponse response) throws Exception {

        List<EstateGoodsManageExcelEntity> estateGoodsManageExcelEntities = baseMapper.queryEstateGoodsManage();
        for (EstateGoodsManageExcelEntity estateGoodsManageExcelEntity : estateGoodsManageExcelEntities) {
            String dutyFreeType = estateGoodsManageExcelEntity.getDutyFreeType();
            String taxRate = estateGoodsManageExcelEntity.getTaxRate();
            String preferentialMark = estateGoodsManageExcelEntity.getPreferentialMark();
            if (taxRate != null && !"".equals(taxRate)) {
                estateGoodsManageExcelEntity.setTaxRate(DecimalFormat(taxRate));
            }
            if ("1".equals(dutyFreeType)) {
                estateGoodsManageExcelEntity.setDutyFreeType("出口免税和其他免税优惠政策(免税)");
            }
            if ("2".equals(dutyFreeType)) {
                estateGoodsManageExcelEntity.setDutyFreeType("不征增值税(不征税)");
            }
            if ("3".equals(dutyFreeType)) {
                estateGoodsManageExcelEntity.setDutyFreeType("普通零税率(0%)");
            } else if ("".equals(dutyFreeType)) {
                estateGoodsManageExcelEntity.setDutyFreeType("");
            }
            if ("0".equals(preferentialMark)) {
                estateGoodsManageExcelEntity.setPreferentialMark("没有优惠政策");
            } else if ("1".equals(preferentialMark)) {
                estateGoodsManageExcelEntity.setPreferentialMark("有优惠政策");
            }
        }
        List<String> cols = ExcelDTO.EstateGoodsManageCols;
        HashMap<String, String> map = new HashMap<>();
        map.put("projectCode", "项目编码");
        map.put("projectName", "项目名称");
        map.put("goodsCode", "商品编码");
        map.put("goodsName", "商品名称");
        map.put("taxRate", "税率");
        map.put("model", "规格型号");
        map.put("unit", "计量单位");
        map.put("taxCode", "税收分类编码");
        map.put("taxName", "税收分类名称");
        map.put("dutyFreeType", "免税类型");
        map.put("preferentialMark", "是否享受优惠政策");
        map.put("preferentialName", "优惠政策名称");
        ExcelUtil.exportExcel(response, cols, map, estateGoodsManageExcelEntities, "地产商品管理信息");
    }

    /**
     * 税率判断
     */
    public boolean rateJudge(String rate) {
        List<String> rates = Arrays.asList("0", "0.01", "0.03", "0.05", "0.06", "0.09", "0.10", "0.11", "0.13", "0.16", "0.17");
        return rates.contains(rate);
    }

    /**
     * 免税类型判断
     */
    public boolean rateNameJudge(String rateName) {
        List<String> rates = Arrays.asList("1", "2", "3");
        return rates.contains(rateName);
    }

    /**
     * 优惠政策判断
     */
    public boolean favouredPolicyJudge(String rate) {
        List<String> fp = Arrays.asList("是", "否");
        return fp.contains(rate);
    }

    /**
     * 优惠政策名称判断
     */
    public boolean favouredPolicyNameJudge(String favouredPolicyName) {
        List<String> PolicyNames = Arrays.asList("00001", "00002", "00003", "00004", "00005", "00006", "00007", "00008", "00009", "00010", "00011", "00012", "免税", "00014", "00015", "00016");
        return PolicyNames.contains(favouredPolicyName);
    }

    public final static Map mkMap = new HashMap();

    static {
        mkMap.put("是", "1");
        mkMap.put("否", "0");
    }

    public final static Map mslxMap = new HashMap();

    static {
        mslxMap.put("1", "出口免税和其他免税优惠政策(免税)");
        mslxMap.put("2", "不征增值税(不征税)");
        mslxMap.put("3", "普通零税率(0%)");
    }

    //税率 格式转化
    public static String DecimalFormat(String s) {
        double a = Double.parseDouble(s);
        DecimalFormat df = new DecimalFormat("0%");
        String r = df.format(a);
        return r;
    }

    public int taxRateJudge(String taxRate, String dutyFreeType) {

        if ("0".equals(taxRate) && StrUtil.isEmpty(dutyFreeType)) {
            return 1;
        }
        if ("0".equals(taxRate) && !StrUtil.isEmpty(dutyFreeType)) {
            if (!rateNameJudge(dutyFreeType)) {
                return 3;
            }
        }
        if (!"0".equals(taxRate) && !StrUtil.isEmpty(dutyFreeType)) {
            return 2;
        }
        return 0;
    }

    public int preferentialJudge(String preferentialMark, String preferentialName) {
        if ("否".equals(preferentialMark) && !StrUtil.isEmpty(preferentialName)) {
            return 1;
        }
        if ("是".equals(preferentialMark) && preferentialName.isEmpty()) {
            return 2;
        }
        if ("是".equals(preferentialMark) && !preferentialName.isEmpty()) {
            if (!favouredPolicyNameJudge(preferentialName)) {
                return 3;
            }
        }
        return 0;
    }
}

